<?php
/***
* @version $Id: functions_message.php 336 2007-01-23 08:12:56Z flexiondotorg $
* @copyright (c) 2006 - 2007 Flexion.Org
*            (c) 2004 - 2005 Project Minerva
*            (c) 2001 - 2006 phpBB Group
* @license   http://opensource.org/licenses/gpl-license.php GNU Public License
***/

if (!defined('IN_R3BORN'))
{
	die('Hacking attempt');
}

$html_entities_match = array('#&(?!(\#[0-9]+;))#', '#<#', '#>#', '#"#');
$html_entities_replace = array('&amp;', '&lt;', '&gt;', '&quot;');

$unhtml_specialchars_match = array('#&gt;#', '#&lt;#', '#&quot;#', '#&amp;#');
$unhtml_specialchars_replace = array('>', '<', '"', '&');

//
// This function will prepare a posted message for
// entry into the database.
//
function prepare_message($message, $html_on, $bbcode_on, $smile_on, $bbcode_uid = 0)
{
	global $config, $html_entities_match, $html_entities_replace;

	//
	// Clean up the message
	//
	$message = trim($message);

	if ($html_on)
	{
		// If HTML is on, we try to make it safe
		// This approach is quite agressive and anything that does not look like a valid tag
		// is going to get converted to HTML entities
		$message = stripslashes($message);
		$html_match = '#<[^\w<]*(\w+)((?:"[^"]*"|\'[^\']*\'|[^<>\'"])+)?>#';
		$matches = array();

		$message_split = preg_split($html_match, $message);
		preg_match_all($html_match, $message, $matches);

		$message = '';

		foreach ($message_split as $part)
		{
			$tag = array(array_shift($matches[0]), array_shift($matches[1]), array_shift($matches[2]));
			$message .= preg_replace($html_entities_match, $html_entities_replace, $part) . clean_html($tag);
		}

		$message = addslashes($message);
		$message = str_replace('&quot;', '\&quot;', $message);
	}
	else
	{
		$message = preg_replace($html_entities_match, $html_entities_replace, $message);
	}

	if($bbcode_on && $bbcode_uid != '')
	{
		$message = bbencode_first_pass($message, $bbcode_uid);
	}

	return $message;
}

function unprepare_message($message)
{
	global $unhtml_specialchars_match, $unhtml_specialchars_replace;

	return preg_replace($unhtml_specialchars_match, $unhtml_specialchars_replace, $message);
}

/**
* Called from within prepare_message to clean included HTML tags if HTML is
* turned on for that post
* @param array $tag Matching text from the message to parse
*/
function clean_html($tag)
{
	global $config;

	if (empty($tag[0]))
	{
		return '';
	}

	$allowed_html_tags = preg_split('/, */', strtolower($config['allow_html_tags']));
	$disallowed_attributes = '/^(?:style|on)/i';

	// Check if this is an end tag
	preg_match('/<[^\w\/]*\/[\W]*(\w+)/', $tag[0], $matches);
	if (sizeof($matches))
	{
		if (in_array(strtolower($matches[1]), $allowed_html_tags))
		{
			return  '</' . $matches[1] . '>';
		}
		else
		{
			return  htmlspecialchars('</' . $matches[1] . '>');
		}
	}

	// Check if this is an allowed tag
	if (in_array(strtolower($tag[1]), $allowed_html_tags))
	{
		$attributes = '';
		if (!empty($tag[2]))
		{
			preg_match_all('/[\W]*?(\w+)[\W]*?=[\W]*?(["\'])((?:(?!\2).)*)\2/', $tag[2], $test);
			for ($i = 0; $i < sizeof($test[0]); $i++)
			{
				if (preg_match($disallowed_attributes, $test[1][$i]))
				{
					continue;
				}
				$attributes .= ' ' . $test[1][$i] . '=' . $test[2][$i] . str_replace(array('[', ']'), array('&#91;', '&#93;'), htmlspecialchars($test[3][$i])) . $test[2][$i];
			}
		}
		if (in_array(strtolower($tag[1]), $allowed_html_tags))
		{
			return '<' . $tag[1] . $attributes . '>';
		}
		else
		{
			return htmlspecialchars('<' . $tag[1] . $attributes . '>');
		}
	}
	// Finally, this is not an allowed tag so strip all the attibutes and escape it
	else
	{
		return htmlspecialchars('<' .   $tag[1] . '>');
	}
}

//
// Fill smiley templates (or just the variables) with smileys
// Either in a window or inline
//
function generate_smilies($mode, $page_id, $page = 'posting')
{
	global $db, $config, $template, $lang, $images, $theme, $phpEx, $root_path;
	global $user_ip, $session_length;//, $starttime;
	global $userdata;

	$inline_columns = 4;
	$inline_rows = 5;
	$window_columns = 8;

	if ($mode == 'window')
	{
		$userdata = session_pagestart($user_ip, $page_id);
		init_userprefs($userdata);

		if (!defined(IN_ADMIN))
		{
			page_header($lang['Emoticons'], true);
		}
		else
		{
			page_header_admin();
		}

		$template->set_filenames(array(
			'smiliesbody' => 'posting_smilies.tpl')
		);
	}

	$sql = "SELECT emoticon, code, smile_url
		FROM " . SMILIES_TABLE . "
		ORDER BY smilies_id";
	if ($result = $db->sql_query($sql))
	{
		$num_smilies = 0;
		$rowset = array();
		while ($row = $db->sql_fetchrow($result))
		{
			if (empty($rowset[$row['smile_url']]))
			{
				$rowset[$row['smile_url']]['code'] = str_replace("'", "\\'", str_replace('\\', '\\\\', $row['code']));
				$rowset[$row['smile_url']]['emoticon'] = $row['emoticon'];
				$num_smilies++;
			}
		}

		if ($num_smilies)
		{
			$smilies_count = ($mode == 'inline') ? min(19, $num_smilies) : $num_smilies;
			$smilies_split_row = ($mode == 'inline') ? $inline_columns - 1 : $window_columns - 1;

			$s_colspan = 0;
			$row = 0;
			$col = 0;

			while (list($smile_url, $data) = @each($rowset))
			{
				if (!$col)
				{
					$template->assign_block_vars('smilies_row', array());
				}

				$template->assign_block_vars('smilies_row.smilies_col', array(
					'SMILEY_CODE' => $data['code'],
					'SMILEY_IMG'  => $images['smiles'] . '/' . $smile_url,
					'SMILEY_DESC' => $data['emoticon'])
				);

				$s_colspan = max($s_colspan, $col + 1);

				if ($col == $smilies_split_row)
				{
					if ($mode == 'inline' && $row == $inline_rows - 1)
					{
						break;
					}
					$col = 0;
					$row++;
				}
				else
				{
					$col++;
				}
			}

			if ($mode == 'inline' && $num_smilies > $inline_rows * $inline_columns)
			{
				$template->assign_block_vars('switch_smilies_extra', array());

				$template->assign_vars(array(
					'L_MORE_SMILIES' => $lang['More_emoticons'],
					'U_MORE_SMILIES' => append_sid($page . '.' . $phpEx . '?mode=smilies'))
				);
			}

			$template->assign_vars(array(
				'L_EMOTICONS' => $lang['Emoticons'],
				'L_CLOSE_WINDOW' => $lang['Close_window'],
				'S_SMILIES_COLSPAN' => $s_colspan)
			);
		}
	}

	if ($mode == 'window')
	{
		$template->pparse('smiliesbody');

		if (!defined(IN_ADMIN))
		{
			page_footer(true);
		}
		else
		{
			page_footer_admin();
		}
	}
}

function parse_message(&$message, $bbcode_uid = '', $enable_html = false, $enable_smilies = false, $max_chars = 0)
{
	global $config, $userdata;

	//
	// Note! The order used for parsing the message _is_ important, moving things around could break any output
	//

	// Trim the message if it is larger than the supplied maximum.	
	if ( intval($max_chars) > 0 && strlen($message) > $max_chars )
	{
		// remove html escape

		$message = unprepare_message($message);
		$message = str_replace('<br />', "\n", $message);

		$enable_bbcode = false;

		// remove bbcode uid
		if ( !empty($bbcode_uid) )
		{			
			$enable_bbcode = true;
			$message = preg_replace('/\:(([a-z0-9]:)?)' . $bbcode_uid . '/s', '', $message);

			// replace img with url
			$message = str_replace(array('[img]', '[/img]'), array('[url]', '[/url]'), $message);
			
		}

		// shorten the message
		if ( strlen($message) + 3 > $max_chars )
		{
			$message = substr($message, 0, $max_chars) . '...';
		}

		// re-add bbCode
		$message = stripslashes(prepare_message(addslashes($message), $enable_html, $enable_bbcode, $enable_smilies, $bbcode_uid));
	}

	//
	// If the board has HTML off but the post has HTML on then we process it, else leave it alone
	//
	if ( !$config['allow_html'] || !$userdata['user_allowhtml'])
	{
		if ( $enable_html )
		{
			$message = preg_replace('#(<)([\/]?.*?)(>)#is', "&lt;\\2&gt;", $message);
		}
	}

	if ($bbcode_uid != '')
	{
		$message = ($config['allow_bbcode']) ? bbencode_second_pass($message, $bbcode_uid) : preg_replace("/\:$bbcode_uid/si", '', $message);
	}

	$message = make_clickable($message);

	//
	// Parse smilies
	//
	if ( $config['allow_smilies'] )
	{
		if ( $enable_smilies )
		{
			$message = smilies_pass($message);
		}
	}

	//
	// Highlight active words (primarily for search)
	//
	$highlight_match = '';
	if (isset($_GET['highlight']))
	{
		// Split words and phrases
		$words = explode(' ', trim(htmlspecialchars($_GET['highlight'])));

		for($i = 0; $i < sizeof($words); $i++)
		{
			if (trim($words[$i]) != '')
			{
				$highlight_match .= (($highlight_match != '') ? '|' : '') . str_replace('*', '\w*', preg_quote($words[$i], '#'));
			}
		}
		unset($words);

		$highlight_match = r3born_rtrim($highlight_match, "\\");
	}

	if ($highlight_match != '')
	{
		// This has been back-ported from 3.0 CVS
		//$message = preg_replace('#(?!<.*)(?<!\w)(' . $highlight_match . ')(?!\w|[^<>]*>)#i', '<b style="color:#'.$theme['fontcolor3'].'">\1</b>', $message);
		$message = preg_replace('#(?!<.*)(?<!\w)(' . $highlight_match . ')(?!\w|[^<>]*>)#i', '<b class="highlight">\1</b>', $message);
	}

	// Replace naughty words
	word_censor($message);

	// Replace newlines
	//$message = nl2br($message);
	$message = str_replace("\n", "\n<br />\n", $message);

}

function parse_signature(&$message, $bbcode_uid = '', $enable_smilies = false)
{
	global $config, $userdata;

	if ($message != '')
	{
		//
		// Note! The order used for parsing the message _is_ important, moving things around could break any output
		//

		//
		// If the board has HTML off then we process it, else leave it alone
		//
		if ( !$config['allow_html'] || !$userdata['user_allowhtml'])
		{
			$message = preg_replace('#(<)([\/]?.*?)(>)#is', "&lt;\\2&gt;", $message);
		}

		if ($bbcode_uid != '')
		{
			$message = ($config['allow_bbcode']) ? bbencode_second_pass($message, $bbcode_uid) : preg_replace("/\:$bbcode_uid/si", '', $message);
		}

		$message = make_clickable($message);

		//
		// Parse smilies
		//
		if ( $config['allow_smilies'] )
		{
			if ( $enable_smilies )
			{
				$message = smilies_pass($message);
			}
		}

		// Replace naughty words
		word_censor($message);

		// Replace newlines
		//$message = '<br />_________________<br />' . nl2br($message);
		$message = '<br />_________________<br />' . str_replace("\n", "\n<br />\n", $message);
	}
}

function word_censor(&$text)
{
	//
	// Replace naughty words
	//
	$orig_word = $replacement_word = array();
	obtain_word_list($orig_word, $replacement_word);

	if (count($orig_word))
	{
		//$text = preg_replace($orig_word, $replacement_word, $text);
		$text = str_replace('\"', '"', substr(@preg_replace('#(\>(((?>([^><]+|(?R)))*)\<))#se', "@preg_replace(\$orig_word, \$replacement_word, '\\0')", '>' . $text . '<'), 1, -1));
	}
}

function strip_javascript($text_in)
{
	$search = array('@<script[^>]*?>.*?</script>@si',  // Strip out javascript
					'@<![\s\S]*?--[ \t\n\r]*>@'        // Strip multi-line comments including CDATA
	);

	$text_out = preg_replace($search, '', $text_in);
	return $text_out;
}

?>